package com.example.yingjiguanli_demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.yingjiguanli_demo.mapper.PostsMapper;
import com.example.yingjiguanli_demo.pojo.Pagination;
import com.example.yingjiguanli_demo.pojo.Posts;
import com.example.yingjiguanli_demo.pojo.Result;
import com.example.yingjiguanli_demo.service.IPostsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.jsoup.Jsoup;
import org.jsoup.safety.Safelist;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.example.yingjiguanli_demo.utils.ConstantUtils.POST_KEY_PREFIX;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author scj
 * @since 2024-11-04
 */
@Service
@Slf4j
public class PostsServiceImpl extends ServiceImpl<PostsMapper, Posts> implements IPostsService {

    @Autowired
    private PostsMapper postsMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /***
     * 添加帖子
     * @param posts *
     * @param userId 用户id
     * @return 添加结果
     */
    @Override
    public Result<T> addPosts(Posts posts, Integer userId) {
        posts.setUserId(userId);
        // 防止XSS攻击：清理用户输入的评论内容
        String Content = posts.getContent();
        if (Content != null) {
            // 使用Jsoup清理内容，移除所有HTML标签，保留纯文本
            Content = Jsoup.clean(Content, Safelist.none());
            // 或者，如果需要保留一些基本标签，可以使用 Safelist.basic()
            posts.setContent(Content);
        }
        int insert = postsMapper.insert(posts);
        if (insert > 0) {
            return Result.success("添加成功");
        }
        return Result.failed("添加失败");

    }

    /**
     * 获取推文的分页结果
     *
     * @param pageNum  当前页码（从 1 开始）
     * @param pageSize 每页推文的数量
     * @return 分页推文结果
     */
    @Override
    public Result<List<Posts>> getPosts(int pageNum, int pageSize) {
        if (pageNum < 1 || pageSize < 1) {
            return Result.forbidden("页码和每页数量必须大于0");
        }

        // 计算分页起始位置
        int offset = (pageNum - 1) * pageSize;

        // 获取推文列表
        List<Posts> postsList = postsMapper.getPostsByPage(offset, pageSize);

        // 获取推文总数量
        int totalPostsCount = postsMapper.getTotalPostsCount();

        // 构建分页响应
        Pagination<Posts> pagination = new Pagination<>();
        pagination.setItems(postsList);
        pagination.setCurrentPage(pageNum);
        pagination.setPageSize(pageSize);
        pagination.setTotalItems(totalPostsCount);
        pagination.setTotalPages((int) Math.ceil((double) totalPostsCount / pageSize));

        return Result.success(pagination.getItems());
    }

    /***
     * 删除帖子
     * @param id 帖子id
     * @return 删除结果
     */
    @Override
    public Result<T> deletePosts(Integer id) {
        int delete = postsMapper.deleteById(id);
        if (delete > 0) {
            return Result.success("删除成功");
        }
        return Result.failed("删除失败");
    }

    @Override
    public Result<List<Posts>> getPostById(Integer id) {
        // 使用常量类定义 Redis key 前缀
        String redisKey = POST_KEY_PREFIX + id;


        // 获取 Redis 中的操作对象
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();

        // 先从 Redis 中查询
        Object cachedPosts = valueOperations.get(redisKey);

        if (cachedPosts != null) {
            log.info("缓存命中，直接返回 Redis 中的数据");
            // 如果缓存中有数据，直接返回缓存的数据
            List<Posts> posts = (List<Posts>) cachedPosts; // 直接强制转换
            return Result.success(posts);
        }

        // 如果缓存中没有，查询数据库
        log.info("缓存未命中，查询数据库");
        QueryWrapper<Posts> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("post_id", id);
        List<Posts> posts = postsMapper.selectList(queryWrapper);

        if (posts != null && !posts.isEmpty()) {
            log.info("查询到数据，缓存到 Redis 中");
            // 将查询结果缓存到 Redis 中
            valueOperations.set(redisKey, posts, 30, TimeUnit.MINUTES); // 缓存30分钟
        }

        return Result.success(posts);
    }
}
